﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class _03虚函数和多态
    {
        public static void Main(string[] args)
        {
            Person pc1 = new Chinese("小明");
            Person pc2 = new Chinese("小王");

            pc1.say();
            pc1.say2();

            Person jp1 = new Janpanese("苗木");
            Person jp2 = new Janpanese("村上");

            Person[] persons = new Person[] { pc1,pc2,jp1,jp2};
            foreach (Person p in persons)
            {
                p.say();
            }

            Console.WriteLine("=========================");
            //虽然抽象类不能直接new但是和Java一样在子类初始化的时候仍然后初始化抽象类
            Animal cat = new Cat();
            cat.Bark();
            Animal dog = new Dog();
            dog.Bark();

            Console.ReadKey();
        }

    }

    //------------- abctract的多态 -------------------

    public class Dog : Animal
    {
        public override void Bark()
        {
            Console.WriteLine("Dog 对抽象类 Animal 的实现!");
        }
    }

    public class Cat : Animal
    {
        public override void Bark()
        {
            Console.WriteLine("Cat 对抽象类 Animal 的实现!");
        }
    }

    //定义一个抽象类,抽象类不允许new出来和Java一样
    public abstract class Animal
    {
        public Animal() { Console.WriteLine("抽象类Animal的构造函数"); }

        public abstract void Bark();//抽象方法不允许实现和Java一样
    }

    //--------- virtual 的多态 ------------
    class Janpanese : Person
    {
        public Janpanese(string name) : base(name) { }

        public override void say()
        {
            Console.WriteLine("我是日本人,我叫:{0}", this.Name);
        }
    }

    class Chinese : Person
    {
        public Chinese(string name) : base(name) { }

        //子类重谢父类的 virtual 修饰的方法
        public override void say()
        {
            Console.WriteLine("我是中国人,我叫:{0}", this.Name);
        }

         public new void say2() {
            Console.WriteLine("我是中国人say2(...)");
        }

    }

    class Person
    {
        string _name;
        public string Name
        {
            set { this._name = value; }
            get { return this._name; }
        }

        public Person(string name)
        {
            this._name = name;
        }

        //父类的方法被 virtual 修饰
        public virtual void say()
        {
            Console.WriteLine("我是人类,我叫:{0}",this.Name);
        }

        public void say2() {
            Console.WriteLine("我是人类say2()");
        }

    }

   

}
